package yunjiao.javatutorials.lang.concurrent;

import java.util.concurrent.*;

/**
 * 基础演示
 *
 * @author yangyunjiao
 */
public class ThreadPoolExecutorExample {

    public static void main(String[] args) {
        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,      // 核心线程数
                5,      // 最大线程数
                60L,    // 空闲线程存活时间
                TimeUnit.SECONDS, // 时间单位
                new ArrayBlockingQueue<>(10), // 工作队列
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );

        // 提交任务
        for (int i = 1; i <= 15; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("执行任务 " + taskId +
                        "，线程：" + Thread.currentThread().getName());
                try {
                    Thread.sleep(2000); // 模拟任务执行
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 监控线程池状态
        monitorThreadPool(executor);

        // 优雅关闭
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    private static void monitorThreadPool(ThreadPoolExecutor executor) {
        ScheduledExecutorService monitor = Executors.newSingleThreadScheduledExecutor();
        monitor.scheduleAtFixedRate(() -> {
            System.out.println("=== 线程池状态 ===");
            System.out.println("活跃线程数: " + executor.getActiveCount());
            System.out.println("核心线程数: " + executor.getCorePoolSize());
            System.out.println("池中最大线程数: " + executor.getLargestPoolSize());
            System.out.println("总任务数: " + executor.getTaskCount());
            System.out.println("已完成任务数: " + executor.getCompletedTaskCount());
            System.out.println("队列大小: " + executor.getQueue().size());
        }, 0, 2, TimeUnit.SECONDS);

        // 监控10秒后关闭
        monitor.schedule(() -> monitor.shutdown(), 10, TimeUnit.SECONDS);
    }
}
